<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style>
			* {
				margin: 0;
				padding: 0;
			}
			html, body {
				width: 100%;
				height: 100%;
			}
			.card {
				display: flex;
				background-color: #eee;
				width: 100%;
				min-height: 50%;
				padding: 10px 20px;
				gap: 20px;
				align-items: baseline;
				flex-wrap: wrap;
			}
			.card-item {
				border-radius: 10px;
				background-color: #fff;
				width: 200px;
				padding: 20px;
				margin-bottom: 10px;
			}
			.card-item-title {
				display: flex;
				justify-content: space-between;
				padding-bottom: 10px;
				margin-bottom: 10px;
				border-bottom: 1px solid #eee;
				cursor: pointer;
			}
			.card-item-title a {
				text-decoration: none;
				color: cornflowerblue;
			}
			li {
				list-style: none;
				font-size: 12px;
			}
			#mask {
				position: fixed;
				width: 100%;
				height: 100%;
				top: 0;
				left: 0;
				z-index: 1;
				background-color: rgba(0, 0, 0, 0.3);
				display: none;
				justify-content: center;
				align-items: center;
			}
			#inner {
			}
		</style>
	</head>
	<body>
		<div id="mask">
			<div id="inner"></div>
		</div>
		<div class="card"></div>
		<button id="addBtn"> 新增节点 </button>
		<a href="https://juejin.cn/post/6844903772968206350#heading-3">flip动画文章</a>
		<script type="text/javascript">
			// https://juejin.cn/post/6844903772968206350#heading-3 配合文章食用
			const card = document.querySelector(".card");
			
			function createDocument(template) {
			  let doc = new DOMParser().parseFromString(`<div id="DOMParser">${template}</div>`, 'text/html');
			  let div = doc.querySelector('#DOMParser').children[0];
			  return div; 
			}
			
			function removeCurrent(e) {
				transition(() => {
					e.preventDefault();
					e.target.parentNode.parentNode.remove();
				})
				// e.preventDefault();
				// e.target.parentNode.parentNode.remove();
			}
			function template(value){
				return `
					<div class="card-item" id="${Math.random().toString(16)}">
						<div class="card-item-title">
							<h3>title-${value}</h3>
							<a href="">delete</a>
						</div>
						<ul>
							<li>content-${value}</li>
							<li>content-${value}</li>
							<li>content-${value}</li>
						</ul>
					</div>
				`;
			}
			const  htmlString = [1, 2, 3, 4, 5].map(item => createDocument(template(item)));
			htmlString.forEach(item => {
				item.querySelector('a').addEventListener('click', this.removeCurrent);
				item.querySelector('h3').addEventListener('click', this.showMask);
				card.appendChild(item);
			});
			/**
			 * f 记录最开始的位置
			 * l 记录结束之后的位置
			 * i 计算一个过程
			 * p 播放动画
			 */
			let firsts = {};
			let lasts = {};
			// 记录开始的点
			function recordFirsts() {
				for (let ele of card.children) {
					const { x, y } = ele.getBoundingClientRect();
					firsts[ele.id] = { x, y };
				}
			}
			// 记录变化后的点
			function recordLasts() {
				for (let ele of card.children) {
					const { x, y } = ele.getBoundingClientRect();
					lasts[ele.id] = { x, y };
				}
			}
			// 写入动画
			function setAnimation() {
				for (let ele of card.children) {
					if (!firsts[ele.id]) continue;
					const offsetX = firsts[ele.id].x - lasts[ele.id].x;
					const offsetY = firsts[ele.id].y - lasts[ele.id].y;
					ele.style.transition = "";
					ele.style.translate = `${offsetX}px ${offsetY}px`;
				}
			}
			function play(delay = 100) {
				setTimeout(() => {
					for (let ele of card.children) {
						ele.style.transition = "1s";
						ele.style.translate = `0 0`;
					}
				}, delay);
			}
			function transition(callBack, delay = 100) {
				recordFirsts();
				callBack();
				recordLasts();
				setAnimation();
				play(delay);
			}
			addBtn.onclick = () => {
				// recordFirsts();
				transition(() => {
					const ele = createDocument(template(card.children.length));
					ele.querySelector('a').addEventListener('click', this.removeCurrent);
					ele.querySelector('h3').addEventListener('click', this.showMask);
					card.insertBefore(ele, card.children[0]);
				});
				// const ele = createDocument(template(card.children.length));
				// ele.querySelector('a').addEventListener('click', this.removeCurrent);
				// card.insertBefore(ele, card.children[0]);
				// recordLasts();
				// setAnimation();
				// play();
			};
			
			// 遮罩
			const mask = document.querySelector("#mask");
			const inner = document.querySelector("#inner");
			let offset = {};
			mask.onclick = () => {
				inner.style.translate = `${offset.x}px ${offset.y}px`;
				setTimeout(() => {
					inner.innerHTML = "";
					mask.style.display = "none";
					inner.style.transition = "";
					inner.style.translate = "";
				}, 500)
			}
			function showMask(e) {
				mask.style.display = "flex";
				const { x: fx, y: fy } = e.target.getBoundingClientRect();
				console.log(e.target.getBoundingClientRect());
				inner.appendChild(e.target.parentNode.parentNode.cloneNode(true));
				const { x: lx, y: ly } = inner.getBoundingClientRect();
				offset = {
					x: fx-lx-20,
					y: fy-ly-20
				}
				inner.style.transformOrigin = "0 0";
				inner.style.translate = `${offset.x}px ${offset.y}px`;
				setTimeout(() => {
					inner.style.transition = ".5s";
					inner.style.translate = `0 0`;
				}, 100);
			}
		</script>
	</body>
</html>